<?php

namespace App\Console\Commands;

use App\handles\SwooleHandler;
use Illuminate\Console\Command;
use App\Services\Logger;
use App\Services\Store;
use Illuminate\Support\Facades\App;

class Swoole extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'swoole {action}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'swoole command';

    protected $serv;

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $action = $this->argument('action');
        switch ($action) {
            case 'server_start':
                $this->server_start();
                break;
            case 'client_start':
                $this->client_start();
                break;
            case 'start':
                $this->start();
                break;
            case 'stop':
                $this->stop();
                break;
            case 'restart':
                $this->restart();
            case 'web_socket':
                $this->webSocket();

                break;
        }
    }

    private function start()
    {
//        $host = '123.207.28.142';
//        $port = 1883;
//
//        $r = new \mqttclient\src\swoole\MqttClient($host, $port, 10017);
//        $r->setAuth('username', 'password');
//        $r->setKeepAlive(60);
//        $r->setLogger(new Logger());
//        $r->setStore(new Store());
//        $r->setTopics(
//            [
//                new \mqttclient\src\subscribe\Topic('test/slim', function ($msg) {
//                    echo "I receive:" . $msg . "\r\n";
//                }),
//                new \mqttclient\src\subscribe\Topic('test/slim3', function (\mqttclient\src\swoole\MqttClient $client, $msg) {
//                    echo "I receive:" . $msg . " for slim3 \r\n";
//                    echo $client->getClientId();
//                })
//            ]
//        );
//
////set trigger
//        $r->on(\mqttclient\src\consts\ClientTriggers::RECEIVE_SUBACK, function (\mqttclient\src\swoole\MqttClient $client) {
//            $client->publish('slim/echo', 'GGXX', \mqttclient\src\consts\Qos::ONE_TIME);
//        });
//
//        $r->connect();
//        $r->publish('test/slim', 'test qos', 2);
//        $client = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC);
//        $client->on("connect", function (\swoole_client $cli) {
//            $cli->send("GET / HTTP/1.1\r\n\r\n");
//        });
//        $client->on("receive", function (\swoole_client $cli, $data) {
//            echo "Receive: $data";
//            $cli->send(str_repeat('A', 100) . "\n");
//            sleep(1);
//        });
//        $client->on("error", function ($error) {
//            echo 'Connect fail:'.json_encode($error);
//        });
//        $client->on("close", function (\swoole_client $cli) {
//            echo "Connection close\n";
//        });
//        $client->connect('10.0.0.16', 80);
        $client = new \swoole_client(SWOOLE_SOCK_TCP);
        if (!$client->connect('192.168.1.110', 55040, -1)) {
            exit("connect failed. Error: {$client->errCode}\n");
        }
        $client->send("hello world\n");
        echo $client->recv();
        $client->close();
    }

    private function server_start()
    {
//        $this->serv = new \swoole_server('192.168.1.241', 55040);
        $this->serv = new \swoole_server('10.0.0.5', 7777);

        //当启动一个Swoole应用时，一共会创建2 + n + m个进程，2为一个Master进程和一个Manager进程，其中n为Worker进程数。m为TaskWorker进程数。

        //默认如果不设置，swoole底层会根据当前机器有多少CPU核数，启动对应数量的Reactor线程和Worker进程。我机器为4核的。Worker为4。TaskWorker为0。

        //下面我来设置worker_num = 10。看下启动了多少个进程

        $this->serv->set([
            'worker_num' => 10,
            //'task_worker_num' => 2,
            'deamonize' => true,
        ]);

        //启动10个work，总共12个进程。
        /*
        ➜  Event git:(master) pstree |grep server.php
    |   \-+= 54172 yangyi php server.php  #Master进程
    |     \-+- 54173 yangyi php server.php  # Manager 进程
    |       |--- 54174 yangyi php server.php  #Work 进程
    |       |--- 54175 yangyi php server.php
    |       |--- 54176 yangyi php server.php
    |       |--- 54177 yangyi php server.php
    |       |--- 54178 yangyi php server.php
    |       |--- 54179 yangyi php server.php
    |       |--- 54180 yangyi php server.php
    |       |--- 54181 yangyi php server.php
    |       |--- 54182 yangyi php server.php
    |       \--- 54183 yangyi php server.php
         *
         */

        //增加新的监控的ip:post:mode
        $this->serv->addlistener("::1", 9500, SWOOLE_SOCK_TCP);

        //监听事件
        /*
         *
         * - onStart
         * - onShutdown
         * - onWorkerStart
         * - onWorkerStop
         * - onTimer
         * - onConnect
         * - onReceive
         * - onClose
         * - onTask
         * - onFinish
         * - onPipeMessage
         * - onWorkerError
         * - onManagerStart
         * - onManagerStop
         */
        $handler = new SwooleHandler();

        $this->serv->on('Start', array($this, 'onStart'));
        $this->serv->on('Connect', array($this, 'onConnect'));
        $this->serv->on('Receive', array($handler, 'onReceive'));
        $this->serv->on('Close', array($this, 'onClose'));

        //master进程启动后, fork出Manager进程, 然后触发ManagerStart
        $this->serv->on('ManagerStart', function (\swoole_server $server) {
            echo "On manager start.";
        });

        //manager进程启动,启动work进程的时候调用 workid表示第几个id, 从0开始。
        $this->serv->on('WorkerStart', function ($serv, $workerId) {
            echo $workerId . '---';
        });

        //当一个work进程死掉后，会触发
        $this->serv->on('WorkerStop', function () {
            echo '--stop';
        });

        //启动
        $this->serv->start();
    }

    //启动server时候会触发。
    public function onStart($serv)
    {
        echo "Start\n";
    }

    //client连接成功后触发。
    public function onConnect($serv, $fd, $from_id)
    {
        $a = $serv->send($fd, "Hello {$fd}!");
        //var_dump($a); //成功返回true
    }

    //接收client发过来的请求
    public function onReceive(\swoole_server $serv, $fd, $from_id, $data)
    {
        echo "Get Message From Client {$fd}:{$data}\n";
        //$serv->send($fd, $data);
        //关闭该work进程
        //$serv->stop();
        //宕机
        //$serv->shutdown();

        //主动关闭 客户端连接,也会触发onClose事件
        //$serv->close($fd);

        $serv->send($fd, $data);

        //$list = $serv->connection_list();
//           foreach ($list as $fd) {
//               $serv->send($fd, $data);
//           }
    }


//客户端断开触发
    public function onClose($serv, $fd, $from_id)
    {
        echo "Client {$fd} close connection\n";
    }


    private function client_start()
    {
        $client = new \swoole_client(SWOOLE_SOCK_TCP);
        if (!$client->connect('10.0.0.5', 7777, -1)) {
            exit("connect failed. Error: {$client->errCode}\n");
        }
//        if (!$client->connect('192.168.1.110',53760, -1)) {
//            exit("connect failed. Error: {$client->errCode}\n");
//        }
        $res = $client->send('{"action":"deviceInfo","data":{"configName":"System","content":{"Who":{"ID":"B1001003","SubID":1,"DHCP":0,"IP":"192.168.1.241","SubMask":"255.255.255.0","GateWay":"192.168.1.1","_MAC":"B8:27:EB:28:31:D9","_Model":"IOTG.W","_ModelID":"270","_ModelSubID":1,"_DB_Version":"1","_SW_Version":"iotk:1.0.00-20161122-003955/iotm:0.0.3-20161201-162553","_IOTQRData":"NUKUUETX6L5G8TA9111A,fba44a3dda4ad58da3b28c9a"}}}}');
        echo $res;
        echo $client->recv();
        $client->close();
    }

    private function stop()
    {

    }

    private function restart()
    {
        $accessKeyId = "LTAIEUPuAc4yGvt2";
        $accessSecret = "RilYp52Bq8muJYwGfWDBphbxMrS8BU";
        $iClientProfile = \DefaultProfile::getProfile("cn-shanghai", $accessKeyId, $accessSecret);
        $client = new \DefaultAcsClient($iClientProfile);
        dd($client);
    }

    public function webSocket()
    {
        $server = new \swoole_websocket_server("0.0.0.0", 8888);
        //服务端接收连接事件
        $server->on('open', function (\swoole_websocket_server $server, $request) {

        });
        //服务端接收信息事件
        $server->on('message', function (\swoole_websocket_server $server, $frame) {

        });
        //服务端接收关闭事件
        $server->on('close', function ($ser, $fd) {

        });
        //服务开启
        $server->start();
    }
}
